/*
 * @Author: Zhang Kai
 * @Date: 2022-05-09 17:18:30
 * @LastEditors: mayijun
 * @LastEditTime: 2022-07-21 18:23:49
 * @FilePath: /metricsx-standard-ui/src/components/GroupTree/index.tsx
 */
//主题树组件
import { defineComponent, onMounted, reactive, ref, watch } from 'vue';
import { ElMessage, ElMessageBox, ElTree } from 'element-plus/lib/index';
import Classfiy from '@/assets/images/classfiy.svg';
import './index.scss';
import { useRoute } from 'vue-router';

const ThemeTree = defineComponent({
  name: 'ThemeTree',
  props: {
    ...ElTree.props,
    /* 删除API函数 */
    delFn: {
      type: Function,
      default: () => {}
    },
    /* tree API函数 */
    listFn: {
      type: Function,
      default: () => {}
    },
    /* 重命名API函数 */
    reNameFn: {
      type: Function,
      default: () => {}
    },
    /* 添加API函数 */
    addFn: {
      type: Function,
      default: () => {}
    },
    /* key */
    groupKey: {
      type: Number,
      default: 1
    },
    /* 分类标题 */
    titles: {
      type: String,
      default: '分类名称'
    },
    /* 是否有操作 */
    isOperate: {
      type: Boolean,
      default: true
    },
    /* 是否需要标题 */
    isTitles: {
      type: Boolean,
      default: () => true
    },
    /* 根节点ID */
    rootId: {
      type: Number
    },
    /* 是否高亮当前选中节点 */
    activeCurrent: {
      type: Boolean,
      default: true
    }
  },
  emits: ['getTreeNode', 'delGroup'],
  setup: (props, { slots, attrs, emit }) => {
    // tree  ref
    const tree: any = ref();
    // 当前选中节点
    const nodeInfo: any = ref({});
    // treeList
    const treeList: any = ref([]);
    // 重命名，新建 名称暂存
    const newOrEditName: any = ref('');
    // 缓存id
    const saveEditId: any = ref();
    // input ref
    const inputRef: any = ref();

    const listLoading = ref(false);

    const toggle = ref({ index: -1 });

    const newNode: any = ref({});

    /* 当前点击的分组id */
    const activeGroupId = ref();

    const route = useRoute();

    // 点击节点展示信息
    const nodeClickToInfo = (node: any) => {
      if (saveEditId.value) {
        tree.value.getNode(saveEditId.value);
      }
      nodeInfo.value = node;
      emit('getTreeNode', node);
    };

    // 添加树层级
    const listLevel = (arr: any, level: number) => {
      arr?.forEach((item: any) => {
        item.level = level;
        if (Array.isArray(item.children) && item.children.length > 0) {
          item.children = listLevel(item.children, level + 1);
        }
      });
      return arr;
    };
    // 获取树list
    const getTreeNodeList = async (params?: any) => {
      // data: 0 场景管理树    data: 1 场景取数树
      let param: any = {
        ...params
      };
      if (route.name === 'IndexScenesManage') {
        param.data = 0;
      }
      if (route.name === 'applicationFetch') {
        param.data = 1;
      }
      listLoading.value = true;
      try {
        const { code, data }: any = await props?.listFn({ ...param });
        if (code === 200) {
          const arr = [];
          arr.push(data);
          treeList.value = listLevel(arr, 1);
        }
      } catch (error) {
        console.log(error);
      } finally {
        listLoading.value = false;
      }
    };

    /******** 右侧菜单 操作********* */
    // 点击右侧菜单项
    const subjectClick = (node: any, data: any, type: string) => {
      // 重命名
      switch (type) {
        case 'reName':
          reNameEdit(data);
          return;
        case 'remove':
          showDelModal(data.id);
          return;
        case 'addUp':
          addUpSubject(data, node?.previousSibling?.data);
          return;
        case 'addNext':
          addNextSubject(data);
          return;
        case 'addSon':
          addSonSubject(data);
          return;
        default:
          return;
      }
    };
    // 名称框失去焦点
    const nameInputOnBlur = (data: any) => {
      newOrEditName.value = '';
      if (data.id != 'new') {
        data.reName = false;
      } else {
        tree.value.remove(data);
      }
    };
    // 重命名操作
    const reNameEdit = (data: any) => {
      // 缓存名称和id
      newOrEditName.value = data.name;
      saveEditId.value = data.id;
      //启动编辑状态
      data.reName = true;
      setTimeout(() => {
        inputRef.value.focus();
      }, 500);
    };

    // 新建分类（input框回车）
    const creatSubject = (e: any, data: any) => {
      newNode.value = {
        name: newOrEditName.value,
        parentId: data.parentId,
        previousId: data.previousId
      };
      if (e.keyCode === 13) {
        if (newOrEditName.value === '') {
          ElMessage.error('名称不能为空！');
        } else {
          // 在上，下，子添加分类
          if (data?.id === 'new' && data) {
            creatNewSubject();
          } else if (data?.id !== 'new' && data) {
            // 重命名
            reNameSubject({ id: data?.id, ...newNode.value });
          } else {
            // 新建一级主题，非右侧菜单
            let previousId = -1;
            if (treeList.value.length > 0) {
              previousId = treeList.value[treeList.value.length - 1].id;
            }
            newNode.value = {
              parentId: -1,
              previousId,
              name: newOrEditName.value
            };
            creatNewSubject();
          }
        }
      }
    };
    // 在上添加
    const addUpSubject = (data: any, preData: any) => {
      newNode.value = {
        id: 'new',
        parentId: data.parentId,
        previousId: preData?.id || -1,
        level: data.level
      };
      tree.value.insertBefore(newNode.value, data);
      setTimeout(() => {
        inputRef.value.focus();
      }, 500);
    };
    // 在下添加
    const addNextSubject = (data: any) => {
      newNode.value = {
        id: 'new',
        parentId: data.parentId,
        previousId: data.id,
        level: data.level
      };
      tree.value.insertAfter(newNode.value, data);
      setTimeout(() => {
        inputRef.value.focus();
      }, 500);
    };
    // 添加子
    const addSonSubject = (data: any) => {
      let previousId = -1;
      if (data.children && data.children.length > 0) {
        previousId = data.children[data.children.length - 1].id;
      }
      newNode.value = {
        id: 'new',
        parentId: data.id,
        previousId,
        level: data.level + 1
      };
      data.children.push(newNode.value);
      tree.value.getNode(data.id).expanded = true;
      setTimeout(() => {
        inputRef.value.focus();
      }, 500);
    };

    // 执行添加操作
    const creatNewSubject = async (params?: any) => {
      try {
        const { code, data } = await props?.addFn({
          ...newNode.value,
          rootId: props?.rootId
        });
        if (code === 200) {
          getTreeNodeList();
          newOrEditName.value = '';
          ElMessage.success('创建成功');
        }
      } catch (error) {
        ElMessage.error('创建失败');
      }
    };

    // 执行重命名
    const reNameSubject = async (params: any) => {
      try {
        const { code, data } = await props?.reNameFn({
          ...params,
          rootId: props?.rootId
        });
        if (code === 200) {
          getTreeNodeList();
          newOrEditName.value = '';
          ElMessage.success('更新成功');
        }
      } catch (error) {
        ElMessage.error('更新失败');
      }
    };

    // 删除
    const showDelModal = async (id: number) => {
      saveEditId.value = id;
      ElMessageBox.alert('', '是否确认删除该分类?', {
        confirmButtonText: '确认删除',
        showCancelButton: true,
        confirmButtonClass: 'message-box-del'
      })
        .then(async () => {
          try {
            const { code, data, msg } = await props?.delFn({ id });
            if (code === 200) {
              getTreeNodeList();
              saveEditId.value = null;
              ElMessage.success('删除成功');
              if (activeGroupId.value == id) {
                activeGroupId.value = null;
              }
            }
          } catch (error) {
            console.log(error);
            ElMessage.error('删除失败');
          }
        })
        .catch(() => {
          ElMessage.info('取消删除');
        });
    };
    // 页面加载后初始化
    onMounted(() => {
      getTreeNodeList();
    });

    watch(
      () => props?.groupKey,
      () => {
        getTreeNodeList();
      }
    );

    return () => {
      const {
        titles,
        isOperate,
        isTitles,
        rootId,
        activeCurrent,
        ...restProps
      } = props;
      return (
        <div class="group-container">
          {isTitles ? <div class="group-title">{titles}</div> : undefined}
          <div class="tree-container">
            <el-tree
              {...restProps}
              v-loading={listLoading.value}
              data={treeList.value}
              default-expanded-keys={[activeGroupId.value || rootId || 1]}
              ref={tree}
              node-key="id"
              expand-on-click-node={false}
              props={{ class: 'groupTree' }}
              highlight-current={activeCurrent}
              indent={12}
              onNode-expand={(item: any) => {
                activeGroupId.value = item.id;
              }}
              v-slots={{
                default: ({ node, data }: any) => (
                  <>
                    {(data.reName || data.id === 'new') && (
                      <el-input
                        v-model={newOrEditName.value}
                        style={{ width: '200px' }}
                        ref={inputRef}
                        onKeyup={(e: any) => {
                          creatSubject(e, data);
                        }}
                        onBlur={() => {
                          nameInputOnBlur(data);
                        }}
                        placeholder="请输入"
                      ></el-input>
                    )}
                    {!data.reName && data.id !== 'new' && (
                      <>
                        <div
                          onMouseenter={() => (toggle.value.index = data?.id)}
                          onMouseleave={() => (toggle.value.index = -1)}
                          class="custom-tree-node"
                        >
                          <div
                            onClick={() => {
                              nodeClickToInfo(data);
                            }}
                            class="custom-tree-node-item"
                          >
                            <el-tooltip
                              effect="dark"
                              content={`${data.name}(${data.number})`}
                              placement="top"
                            >
                              <span class="node-name">
                                {`${data.name}(${data.number})`}
                              </span>
                            </el-tooltip>
                          </div>
                          {isOperate ? (
                            <el-dropdown
                              trigger="click"
                              onCommand={(command: string) => {
                                subjectClick(node, data, command);
                              }}
                              v-slots={{
                                dropdown: () => (
                                  <>
                                    <el-dropdown-menu class="theme-dropdown">
                                      {data.id === rootId || data.id === 1 ? (
                                        <el-dropdown-item command="addSon">
                                          添加子分类
                                        </el-dropdown-item>
                                      ) : (
                                        <>
                                          <el-dropdown-item command="reName">
                                            重命名
                                          </el-dropdown-item>

                                          <el-dropdown-item command="addUp">
                                            上方添加分类
                                          </el-dropdown-item>

                                          <el-dropdown-item command="addNext">
                                            下方添加分类
                                          </el-dropdown-item>

                                          {data?.level < 6 && (
                                            <el-dropdown-item command="addSon">
                                              添加子分类
                                            </el-dropdown-item>
                                          )}
                                          {(!data.children ||
                                            data.children?.length === 0) && (
                                            <el-dropdown-item command="remove">
                                              删除
                                            </el-dropdown-item>
                                          )}
                                        </>
                                      )}
                                    </el-dropdown-menu>
                                  </>
                                )
                              }}
                            >
                              {toggle.value.index === data?.id ? (
                                <span class="el-dropdown-link">· · ·</span>
                              ) : undefined}
                            </el-dropdown>
                          ) : undefined}
                        </div>
                      </>
                    )}
                  </>
                )
              }}
            ></el-tree>
          </div>
        </div>
      );
    };
  }
});

export default ThemeTree;
